Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #142 +/- ##
========================================
Coverage 65.73% 65.74%
========================================
Files 1131 1131
Lines 57446 57508 +62
Branches 4327 4332 +5
========================================
+ Hits 37760 37806 +46
- Misses 19686 19702 +16 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Ozaq
left a comment
There was a problem hiding this comment.
While you are at this class, I would also encourage you to add some class level doc and describe the accepted format variants and to be expected exceptions
src/eckit/types/Time.cc
Outdated
| throw BadTime("Unkown format for time: " + s); | ||
| } else { | ||
| throw SeriousBug("Unhandled time format!"); |
There was a problem hiding this comment.
Why is there a need for two different exceptions? I understand the intent of those exception types as follows:
BadTimeis best described as a usage error, as in it was called asTime("ABCD")SeriousBugrepresents an implementation error such asTime("20:11:24")not getting parsed properly.
Is that second throw giving any additional benefits?
src/eckit/types/Time.cc
Outdated
|
|
||
| // DIGITS: "^-?[0-9]+$" | ||
| // FLOAT: "^-?[0-9]*\\.[0-9]+$" | ||
| enum class TimeFormat { UNKOWN, OTHER, DIGITS, DECIMAL }; |
There was a problem hiding this comment.
UNKNOWN is treated as erroneous input, it go stronger in the name and call it INVALID
src/eckit/types/Time.cc
Outdated
| ss = sec; | ||
| } else if (format == TimeFormat::OTHER) { | ||
| std::smatch m; | ||
| if (std::regex_match(s, m, hhmmss_)) { |
src/eckit/types/Time.cc
Outdated
| ss += 60 * (mm + 60 * (hh + 24 * dd)); | ||
| if (s[0] == '-') { | ||
| ss = -ss; | ||
| } else if (std::regex_match(s, m, ddhhmmss_)) { |
| for (auto i = start; i < time.length(); i++) { | ||
| if (time[i] == '.') { | ||
| if (hasDecimal || i == time.length() - 1) { return TimeFormat::UNKOWN; } | ||
| hasDecimal = true; | ||
| } else if (isdigit(time[i]) == 0) { | ||
| return TimeFormat::OTHER; | ||
| } else { | ||
| hasDigit = true; | ||
| } | ||
| } |
There was a problem hiding this comment.
I think this can be done with a single pass over the input string and then return the typeid of the found variant (pretty similar to what you are doing already) plus up to 5 tokens, 1 token for the sign and 4 for positive integers (day, hour, minute, second).
Subsequent code can then validate on this result, e.g. was the extended flag passed.
I am thinking along the lines of:
struct tokenized_time {
FormatType type;
std::string_view sign;
std::string_view integers[4];
};
try to avoid
std::regex